
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

static char * g_accessing = NULL;

int read_line(int fd, char * out, int outlen, const char * delimiter)
{
    char c = 0;

    int total = 0;
    while (total < outlen) {
        int ret = read(fd, &c, 1);
        if (ret <= 0) {
            break;
        }
        if (strchr(delimiter, c) != NULL) {
            break;
        }
        out[total] = c;
        total++;
    }

    return total;
}

void show_maps(const char * message)
{
    printf("----------------------- %s -------------------------\n", message);
    int fd = open("/proc/self/maps", O_RDONLY);
    if (fd < 0) {
        perror("open");
        return;
    }
    char    line[10240];
    int ret = 0;

    while ((ret = read_line(fd, line, sizeof(line) - 1, "\n")) > 0) {
        line[ret] = 0;
        // if (strstr(line, " rw-p ") != NULL) {
            printf("%s\n", line);
        // }
    }
    close(fd);
}

void signal_handler(int sig)
{
    printf("current accessing: %p\n", g_accessing);

    char temp[100];
    sprintf(temp, "signal %d", sig);

    show_maps(temp);
    exit(0);
}

int main()
{
    signal(SIGSEGV, signal_handler);
    signal(SIGINT, signal_handler);
    signal(SIGKILL, signal_handler);

    int i, j;
    char *p[1024] = {0};

    for (i = 0; i < 50; i++) {
        p[i] = malloc(1 << 20);
        memset(p[i], 0, 1 << 20);
    }

    // show_maps("init");
    while (1) {
        for (i = 0; i < 50; i++) {
            g_accessing = p[i];
            for (j = 0; j < (1 << 20); j++) {
                // printf("%p\n", g_accessing);
                (*g_accessing)++;
                g_accessing++;
            }

            // check
            for (j = 0; j < (1 << 20); j++) {
                if (p[i][j] != p[i][0]) {
                    printf("data had been changed! pointer = %p\n", &p[i][j]);
                    show_maps("changed");
                }
            }
        }
        // sleep(1);
    }

    return 0;
}














